<?php

namespace App\Logic;

use Hyperf\Utils\Context;
use League\Flysystem\FileNotFoundException;
use League\Flysystem\Filesystem;
use Psr\Container\ContainerInterface;

class Dictionary
{

    /**
     * @var ContainerInterface
     */
    private $container;

    /**
     * @var Filesystem
     */
    private $filesystem;

    private function setFilename($val)
    {
        Context::set('dictionary.filename', $val);
    }

    private function filename()
    {
        return Context::get('dictionary.filename');
    }

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    public function extDict()
    {
        $this->setFilename('ext_dict.dic');
        return $this;
    }

    public function extStopWords()
    {
        $this->setFilename('ext_stopwords.dic');
        return $this;
    }

    /**
     * 设置文件操作驱动
     * @param Filesystem $filesystem
     * @return $this
     */
    public function setFilesystem(Filesystem $filesystem)
    {
        $this->filesystem = $filesystem;
        return $this;
    }

    private function initFilesystem()
    {
        if (is_null($this->filesystem)) {
            $this->filesystem = $this->container->get(Filesystem::class);
        }
    }

    /**
     * 写内容
     * @param array $content
     */
    public function write(array $content)
    {
        $this->initFilesystem();

        $this->filesystem->put($this->filename(), implode(PHP_EOL, array_unique($content)));
    }

    /**
     * 追加词
     * @param array $content
     * @return bool
     */
    public function append(array $content)
    {
        $this->initFilesystem();
        $origin = $this->read();
        $origin = array_filter(array_merge($origin, $content));
        return $this->filesystem->put($this->filename(), implode(PHP_EOL, array_unique($origin)));
    }

    /**
     * 移除指定词
     * @param array $words
     * @return bool
     */
    public function remove(array $words)
    {
        $this->initFilesystem();
        $origin = $this->read();
        $origin = array_filter($origin, function ($val) use ($words) {
            return !in_array($val, $words);
        });
        return $this->filesystem->put($this->filename(), implode(PHP_EOL, $origin));
    }

    /**
     * 读内容
     * @return array
     */
    public function read(): array
    {
        $this->initFilesystem();
        if ($this->filesystem->has($this->filename())) {
            try {
                return explode(PHP_EOL, $this->filesystem->read($this->filename()));
            } catch (FileNotFoundException $e) {
                // ignore
                return [];
            }
        }
        return [];
    }

    /**
     * 清洗词典
     * @return bool
     */
    public function flush(): bool
    {
        if ($this->filesystem->has($this->filename())) {
            try {
                return $this->filesystem->delete($this->filename());
            } catch (FileNotFoundException $e) {
                return true;
            }
        }
        return true;
    }

    /**
     * 读词典
     * @return string
     */
    public function dic(): string
    {
        return implode("\n", $this->read());
    }

    /**
     * 获取最后修改时间
     * @return string
     */
    public function lastModified(): string
    {
        try {
            $timestamp = $this->filesystem->getTimestamp($this->filename());
        } catch (FileNotFoundException $e) {
            $timestamp = null;
        }

        if ($timestamp) {
            return gmdate('l, d F Y H:i:s T', $timestamp);
        }
        return '';
    }

}